home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Personal Computer World 2009 February
/
PCWFEB09.iso
/
Software
/
Linux
/
Kubuntu 8.10
/
kubuntu-8.10-desktop-i386.iso
/
casper
/
filesystem.squashfs
/
usr
/
share
/
hplip
/
copier
/
copier.py
< prev
Wrap
Text File
|
2008-10-13
|
14KB
|
381 lines
# -*- coding: utf-8 -*-
#
# (c) Copyright 2003-2007 Hewlett-Packard Development Company, L.P.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Author: Don Welch
#
from __future__ import generators
# Std Lib
import sys
import os
import os.path
import time
import threading
import Queue
from cStringIO import StringIO
# Local
from base.g import *
from base.codes import *
from base import device, utils, status, pml
# Event queue values (UI ==> Copy thread)
COPY_CANCELED = 1
# Update queue values (Copy thread ==> UI)
STATUS_IDLE = 0
STATUS_SETTING_UP = 1
STATUS_WARMING_UP = 2
STATUS_ACTIVE = 3
STATUS_DONE = 4
STATUS_ERROR = 5
# PML Copier Only
class PMLCopyDevice(device.Device):
def __init__(self, device_uri=None, printer_name=None,
service=None, callback=None):
device.Device.__init__(self, device_uri, printer_name,
service, callback)
self.copy_thread = None
def copy(self, num_copies=1, contrast=0, reduction=100,
quality=pml.COPIER_QUALITY_NORMAL,
fit_to_page=pml.COPIER_FIT_TO_PAGE_ENABLED,
scan_style=SCAN_STYLE_FLATBED,
update_queue=None, event_queue=None):
if not self.isCopyActive():
self.copy_thread = PMLCopyThread(self, num_copies, contrast, reduction, quality,
fit_to_page, scan_style, update_queue, event_queue)
self.copy_thread.start()
return True
else:
return False
def isCopyActive(self):
if self.copy_thread is not None:
return self.copy_thread.isAlive()
else:
return False
def waitForCopyThread(self):
if self.copy_thread is not None and \
self.copy_thread.isAlive():
self.copy_thread.join()
class PMLCopyThread(threading.Thread):
def __init__(self, dev, num_copies, contrast, reduction, quality,
fit_to_page, scan_style,
update_queue=None, event_queue=None):
threading.Thread.__init__(self)
self.dev = dev
self.num_copies = num_copies
self.contrast = contrast
self.reduction = reduction
self.quality = quality
self.fit_to_page = fit_to_page
self.scan_style = scan_style
self.event_queue = event_queue
self.update_queue = update_queue
self.prev_update = ''
self.copy_type = self.dev.copy_type
log.debug("Copy-type = %d" % self.copy_type)
def run(self):
STATE_DONE = 0
STATE_ERROR = 5
STATE_ABORTED = 10
STATE_SUCCESS = 20
STATE_BUSY = 25
STATE_SET_TOKEN = 30
STATE_SETUP_STATE = 40
STATE_SETUP_PARAMS = 50
STATE_START = 60
STATE_ACTIVE = 70
STATE_RESET_TOKEN = 80
state = STATE_SET_TOKEN
while state != STATE_DONE: # ------------------------- Copier Thread
# revisit - Checking cancel and setting state here means
# every state can unconditionally transition to STATE_ABORTED.
# This has not been verified.
# if self.check_for_cancel():
# state = STATE_ABORTED
if state == STATE_ABORTED:
log.debug("%s State: Aborted" % ("*"*20))
self.write_queue(STATUS_DONE) # This was STATUS_ERROR.
state = STATE_RESET_TOKEN
if state == STATE_ERROR:
log.debug("%s State: Error" % ("*"*20))
self.write_queue(STATUS_ERROR)
state = STATE_RESET_TOKEN
elif state == STATE_SUCCESS:
log.debug("%s State: Success" % ("*"*20))
self.write_queue(STATUS_DONE)
state = STATE_RESET_TOKEN
elif state == STATE_BUSY:
log.debug("%s State: Busy" % ("*"*20))
self.write_queue(STATUS_ERROR)
state = STATE_RESET_TOKEN
elif state == STATE_SET_TOKEN:
log.debug("%s State: Acquire copy token" % ("*"*20))
self.write_queue(STATUS_SETTING_UP)
try:
result_code, token = self.dev.getPML(pml.OID_COPIER_TOKEN)
except Error:
log.debug("Unable to acquire copy token (1).")
state = STATE_SETUP_STATE
else:
if result_code > pml.ERROR_MAX_OK:
state = STATE_SETUP_STATE
log.debug("Skipping token acquisition.")
else:
token = time.strftime("%d%m%Y%H:%M:%S", time.gmtime())
log.debug("Setting token: %s" % token)
try:
self.dev.setPML(pml.OID_COPIER_TOKEN, token)
except Error:
log.error("Unable to acquire copy token (2).")
state = STATUS_ERROR
else:
result_code, check_token = self.dev.getPML(pml.OID_COPIER_TOKEN)
if check_token == token:
state = STATE_SETUP_STATE
else:
log.error("Unable to acquire copy token (3).")
state = STATE_ERROR
elif state == STATE_SETUP_STATE:
log.debug("%s State: Setup state" % ("*"*20))
if self.copy_type == COPY_TYPE_DEVICE:
result_code, copy_state = self.dev.getPML(pml.OID_COPIER_JOB)
if copy_state == pml.COPIER_JOB_IDLE:
self.dev.setPML(pml.OID_COPIER_JOB, pml.COPIER_JOB_SETUP)
state = STATE_SETUP_PARAMS
else:
state = STATE_BUSY
elif self.copy_type == COPY_TYPE_AIO_DEVICE:
result_code, copy_state = self.dev.getPML(pml.OID_SCAN_TO_PRINTER)
if copy_state == pml.SCAN_TO_PRINTER_IDLE:
state = STATE_SETUP_PARAMS
else:
state = STATE_BUSY
elif state == STATE_SETUP_PARAMS:
log.debug("%s State: Setup Params" % ("*"*20))
if self.num_copies < 0: self.num_copies = 1
if self.num_copies > 99: self.num_copies = 99
if self.copy_type == COPY_TYPE_DEVICE: # MFP
# num_copies
self.dev.setPML(pml.OID_COPIER_JOB_NUM_COPIES, self.num_copies)
# contrast
self.dev.setPML(pml.OID_COPIER_JOB_CONTRAST, self.contrast)
# reduction
self.dev.setPML(pml.OID_COPIER_JOB_REDUCTION, self.reduction)
# quality
self.dev.setPML(pml.OID_COPIER_JOB_QUALITY, self.quality)
# fit_to_page
if self.scan_style == SCAN_STYLE_FLATBED:
self.dev.setPML(pml.OID_COPIER_JOB_FIT_TO_PAGE, self.fit_to_page)
else: # AiO
# num_copies
self.dev.setPML(pml.OID_COPIER_NUM_COPIES_AIO, self.num_copies)
# contrast
self.contrast = (self.contrast * 10 / 25) + 50
self.dev.setPML(pml.OID_COPIER_CONTRAST_AIO, self.contrast)
if self.fit_to_page == pml.COPIER_FIT_TO_PAGE_ENABLED:
self.reduction = 0
# reduction
self.dev.setPML(pml.OID_COPIER_REDUCTION_AIO, self.reduction)
# quality
self.dev.setPML(pml.OID_COPIER_QUALITY_AIO, self.quality)
self.dev.setPML(pml.OID_PIXEL_DATA_TYPE, pml.PIXEL_DATA_TYPE_COLOR_24_BIT)
self.dev.setPML(pml.OID_COPIER_SPECIAL_FEATURES, pml.COPY_FEATURE_NONE)
self.dev.setPML(pml.OID_COPIER_PHOTO_MODE, pml.ENHANCE_LIGHT_COLORS | pml.ENHANCE_TEXT)
# tray select
self.dev.setPML(pml.OID_COPIER_JOB_INPUT_TRAY_SELECT, pml.COPIER_JOB_INPUT_TRAY_1)
# media type
self.dev.setPML(pml.OID_COPIER_MEDIA_TYPE, pml.COPIER_MEDIA_TYPE_AUTOMATIC)
# pixel data type
self.dev.setPML(pml.OID_PIXEL_DATA_TYPE, pml.PIXEL_DATA_TYPE_COLOR_24_BIT)
# special features
self.dev.setPML(pml.OID_COPIER_SPECIAL_FEATURES, pml.COPY_FEATURE_NONE)
# media size
self.dev.setPML(pml.OID_COPIER_JOB_MEDIA_SIZE, pml.COPIER_JOB_MEDIA_SIZE_US_LETTER)
log.debug("num_copies = %d" % self.num_copies)
log.debug("contrast= %d" % self.contrast)
log.debug("reduction = %d" % self.reduction)
log.debug("quality = %d" % self.quality)
log.debug("fit_to_page = %d" % self.fit_to_page)
state = STATE_START
elif state == STATE_START:
log.debug("%s State: Start" % ("*"*20))
if self.copy_type == COPY_TYPE_DEVICE:
self.dev.setPML(pml.OID_COPIER_JOB, pml.COPIER_JOB_START)
elif self.copy_type == COPY_TYPE_AIO_DEVICE:
self.dev.setPML(pml.OID_SCAN_TO_PRINTER, pml.SCAN_TO_PRINTER_START)
state = STATE_ACTIVE
elif state == STATE_ACTIVE:
log.debug("%s State: Active" % ("*"*20))
if self.copy_type == COPY_TYPE_DEVICE:
while True:
result_code, copy_state = self.dev.getPML(pml.OID_COPIER_JOB)
if self.check_for_cancel():
self.dev.setPML(pml.OID_COPIER_JOB, pml.COPIER_JOB_IDLE) # cancel
state = STATE_ABORTED
break
if copy_state == pml.COPIER_JOB_START:
log.debug("state = start")
time.sleep(1)
continue
if copy_state == pml.COPIER_JOB_ACTIVE:
self.write_queue(STATUS_ACTIVE)
log.debug("state = active")
time.sleep(2)
continue
elif copy_state == pml.COPIER_JOB_ABORTING:
log.debug("state = aborting")
state = STATE_ABORTED
break
elif copy_state == pml.COPIER_JOB_IDLE:
log.debug("state = idle")
state = STATE_SUCCESS
break
elif self.copy_type == COPY_TYPE_AIO_DEVICE:
while True:
result_code, copy_state = self.dev.getPML(pml.OID_SCAN_TO_PRINTER)
if self.check_for_cancel():
self.dev.setPML(pml.OID_SCAN_TO_PRINTER, pml.SCAN_TO_PRINTER_IDLE) # cancel
state = STATE_ABORTED
break
if copy_state == pml.SCAN_TO_PRINTER_START:
log.debug("state = start")
time.sleep(1)
continue
if copy_state == pml.SCAN_TO_PRINTER_ACTIVE:
self.write_queue(STATUS_ACTIVE)
log.debug("state = active")
time.sleep(2)
continue
elif copy_state == pml.SCAN_TO_PRINTER_ABORTED:
log.debug("state = aborting")
state = STATE_ABORTED
break
elif copy_state == pml.SCAN_TO_PRINTER_IDLE:
log.debug("state = idle")
state = STATE_SUCCESS
break
elif state == STATE_RESET_TOKEN:
log.debug("%s State: Release copy token" % ("*"*20))
try:
self.dev.setPML(pml.OID_COPIER_TOKEN, '\x00'*16)
except Error:
log.error("Unable to release copier token.")
self.dev.close() # Close the device.
state = STATE_DONE
def check_for_cancel(self):
canceled = False
while self.event_queue.qsize():
try:
event = self.event_queue.get(0)
if event == COPY_CANCELED:
canceled = True
log.debug("Cancel pressed!")
except Queue.Empty:
break
return canceled
def write_queue(self, message):
if self.update_queue is not None and message != self.prev_update:
self.update_queue.put(message)
time.sleep(0)
self.prev_update = message